package com.colabo.j2ee.web.oaf.monitorperspective.impl;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.colabo.j2ee.web.core.exception.ServiceException;
import com.colabo.j2ee.web.core.service.impl.DefaultServiceImpl;
import com.colabo.j2ee.web.oaf.monitorperspective.IScheduledTaskManagerService;
import com.colabo.j2ee.web.oaf.monitorperspective.ITask;
import com.colabo.j2ee.web.oaf.vo.IPScheduledTaskVO;

/**
 * 定时任务
 */
public class ScheduledTaskManagerServiceImpl extends DefaultServiceImpl implements IScheduledTaskManagerService{
	private static final Log logger = LogFactory.getLog(ScheduledTaskManagerServiceImpl.class);
	/**
	 * 任务列表
	 */
	private static Map TASKS = new HashMap();	
	
	private static String HOST_NAME = "";
	static {
		InetAddress addr;
		try {
			addr = InetAddress.getLocalHost();
			HOST_NAME = addr.getHostName();
		} catch (UnknownHostException e) {			
			logger.error(e);
			e.printStackTrace();
		}
		
	}

	/**
	 * 增加任务到任务列表
	 * 
	 * @param taskCode
	 *            任务编码
	 * @param task
	 *            任务对象
	 */
	public synchronized void addTask(String taskCode, ITask task) {
		TASKS.put(taskCode, task);
	}

	/**
	 * 停止任务
	 * 
	 * @param taskCode
	 *            任务编号
	 * @throws Exception
	 */
	public synchronized void shutdown(String taskCode) throws ServiceException {
		Object obj = TASKS.get(taskCode);

		if (null == obj) {
			return;
		}

		ITask task = (ITask) obj;
		try {
			task.stopTask();
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		TASKS.remove(taskCode);
	}

	private static ITask getInstance(String className) throws ServiceException {
		
		try{
			Class c = Class.forName(className);		
			ITask task = (ITask) c.newInstance();
			return task;
		}catch(Exception e){
			throw new ServiceException(e);
		}
	}

	public ITask startTask(String taskCode, String express) throws ServiceException {
		ITask task = null;
		
		IPScheduledTaskVO vo = null;
		
		List list = (List)find_Hibernate_NamedQuery(IPScheduledTaskVO.class.getName() +".findScheduleTask", new Object[] { taskCode },-1,-1,false)[0];
		
		vo = (IPScheduledTaskVO)list.get(0);
				
		if(vo==null){
			throw new ServiceException("Can't find the info of task code:"+taskCode);
		}
		
		if("0".equalsIgnoreCase(vo.getStatus())){
			return null;
		}
		
		String className = vo.getTaskClass();		
		task = getInstance(className);
		try {
			task.startTask(express);
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		addTask(taskCode, task);
		return task;
	}

	public ITask startTask(String taskCode, String className, String express) throws ServiceException {
		ITask task = getInstance(className);
		try {
			task.startTask(express);
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		addTask(taskCode, task);
		return task;
	}
	
	public ITask startTask(String hostName, String taskCode, String className, String express) throws ServiceException {
		if(null==hostName||hostName.length()<1||hostName.equalsIgnoreCase(HOST_NAME)){
			ITask task = getInstance(className);
			try {
				task.startTask(express);
			} catch (Exception e) {
				throw new ServiceException(e);
			}
			addTask(taskCode, task);
			return task;
		}
		return null;
	}

	public void init() throws ServiceException {	
		try{
			String taskKey   = "";
			String taskCode  = "";
			String express   = "";
			String className = "";
			String hostName  = "";
			
			//修改支持集群
//			List list = this.findAll_Hibernate_NamedQuery(IPScheduleTaskVO.class.getName() + ".findValidScheduleTask");
//			
//			int count = list.size();
//			IPScheduleTaskVO vo = null;
//			for(int i=0;i<count;i++){
//				vo = (IPScheduleTaskVO)list.get(i);
//				
//				taskCode  = vo.getTaskCode();
//				express   = vo.getTaskConf();
//				className = vo.getTaskClass();
//				String host = vo.getHostName();
//				
//				if(null==host||host.length()<1||host.equalsIgnoreCase(HOST_NAME)){
//					try{
//						startTask(taskCode, className, express);
//					}catch(Exception ex){
//						ex.printStackTrace();
//					}
//				}
				
			String sql = "SELECT TASKKEY,TASKCODE,TASKCONF,TASKCLASS,HOST_NAME,MODIFIED FROM IP_SCHEDULE_TASK WHERE STATUS='1' for update";			
			String update = "update ip_schedule_task set MODIFIED='n' where TASKKEY = ";
			
			boolean hasTra = false;
			Connection conn = getJdbcTemplate().getDataSource().getConnection();
			try{
				try{conn.setAutoCommit(false);}catch(Exception exa){hasTra = true;}
				
				Statement st = conn.createStatement();			
				Statement st2 = conn.createStatement();	
				ResultSet rs = st.executeQuery(sql);
				
				while(rs.next()){
					taskKey = rs.getString("TASKKEY"); 
					taskCode = rs.getString("TASKCODE"); 
					express  = rs.getString("TASKCONF");
					className = rs.getString("TASKCLASS");
					hostName = rs.getString("HOST_NAME");
					
					if(null==hostName||hostName.length()<1||hostName.equalsIgnoreCase(HOST_NAME)){
						try{
							startTask(taskCode, className, express);
							st2.execute(update+"'"+taskKey+"'");
						}catch(Exception ex){
							ex.printStackTrace();
							logger.error(ex);
						}
					}				
				}
				
				rs.close();
				if(!hasTra){
					conn.commit();
				}
				st.close();
				st2.close();
			}catch(Exception exc){
				conn.rollback();
//				exc.printStackTrace();
				logger.error(exc);
			}finally{
				conn.close();
			}
		}catch(Exception e){
//			e.printStackTrace();
			logger.error(e);
		}
	}
	
	/**
	 * 启动修改过的任务
	 * @throws ServiceException
	 */
	public void refresh() throws ServiceException {	
		try{
			String taskKey   = "";
			String taskCode  = "";
			String express   = "";
			String className = "";
			String hostName  = "";
			String status    = "";

				
			String sql = "SELECT TASKKEY,TASKCODE,TASKCONF,TASKCLASS,HOST_NAME,MODIFIED,STATUS FROM IP_SCHEDULE_TASK WHERE MODIFIED='y' for update";			
			String update = "update ip_schedule_task set MODIFIED='n' where TASKKEY = ";
			
			boolean hasTra = false;
			Connection conn = getJdbcTemplate().getDataSource().getConnection();
			try{
				try{conn.setAutoCommit(false);}catch(Exception exa){hasTra = true;}
				
				Statement st = conn.createStatement();			
				Statement st2 = conn.createStatement();	
				ResultSet rs = st.executeQuery(sql);
//				System.out.println("开始检查。。。");
				while(rs.next()){
					taskKey = rs.getString("TASKKEY"); 
					taskCode = rs.getString("TASKCODE"); 
					express  = rs.getString("TASKCONF");
					className = rs.getString("TASKCLASS");
					hostName = rs.getString("HOST_NAME");
					status = rs.getString("STATUS");
					
//					System.out.println("检查:"+hostName+". taskCode:"+taskCode);
					if("0".equalsIgnoreCase(status)){
						System.out.println("stop job:"+taskCode);
						shutdown(taskCode);
//						st2.execute(update+"'"+taskKey+"'");
					}else if(null==hostName||hostName.length()<1||hostName.equalsIgnoreCase(HOST_NAME)){
						try{
							System.out.println("stop job:"+taskCode);
							shutdown(taskCode);
							System.out.println("start job:"+taskCode);
							startTask(taskCode, className, express);
							System.out.println("修改数据库:"+taskKey);
							st2.execute(update+"'"+taskKey+"'");
							System.out.println("结束修改数据库:"+taskKey);
						}catch(Exception ex){
//							ex.printStackTrace();
							logger.error(ex);
						}
					}else{
						System.out.println("stop job:"+taskCode);
						shutdown(taskCode);
//						st2.execute(update+"'"+taskKey+"'");
					}			
				}
//				System.out.println("结束检查");
				
				rs.close();
				if(!hasTra){conn.commit();}			
				st.close();
				st2.close();
			}catch(Exception exc){
				conn.rollback();
//				exc.printStackTrace();
				logger.error(exc);
			}finally{
				conn.close();
			}
		}catch(Exception e){
//			e.printStackTrace();
			logger.error(e);
		}
	}

	public void shutdown(String hostName, String taskCode) throws ServiceException {
		Object obj = TASKS.get(taskCode);

		if (null == obj) {
			return;
		}

		ITask task = (ITask) obj;
		try {
			task.stopTask();
		} catch (Exception e) {
			throw new ServiceException(e);
		}
		TASKS.remove(taskCode);
	}
}
